/*********************************************
 * Copyright (c) 2010 ICBC.
 * All rights reserved.
 * Created on 2010-7-9 

 * Contributors:
 *     dccb-zhouh - initial implementation
 *********************************************/
package com.icbc.ctpdemo.user.opstep;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit; 
import java.awt.image.BufferedImage;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import javax.imageio.ImageIO;

import com.icbc.cte.base.TranFailException;
import com.icbc.ctp.core.IContext;
import com.icbc.ctp.core.annotations.Input;
import com.icbc.ctp.core.annotations.Output;
import com.icbc.ctp.core.impl.OperationStep;

@Input(name = { "xPosition", "yPosition", "destWidth", "destHeight",
		"fullFilePath" }, type = { "String", "String", "String", "String",
		"String" }, description = { "", "" }, mustInput = { true, true, true,
		true, true, true }, isVariable = { true, true, true, true, true, true })
@Output(name = { "destFilePath", "fileCutStream" }, type = { "String",
		"java.io.InputStream" }, description = { "", "" })
public class PicCutOpStep extends OperationStep {

	@Override
	protected int execute(IContext context) throws TranFailException {

		String xPosition = (String) getInputValue(context, "xPosition");
		String yPosition = (String) getInputValue(context, "yPosition");
		String destWidth = (String) getInputValue(context, "destWidth");
		String destHeight = (String) getInputValue(context, "destHeight");

		int x = Integer.parseInt(xPosition);
		int y = Integer.parseInt(yPosition);
		int width = Integer.parseInt(destWidth);
		int height = Integer.parseInt(destHeight);

		String srcFilePath = (String) getInputValue(context, "fullFilePath");
		int tmp = srcFilePath.lastIndexOf('.');
		String destFilePath = srcFilePath.substring(0, tmp) + "cc."
				+ srcFilePath.substring(tmp + 1);
		abscut(destFilePath, srcFilePath, x, y, width, height);
		setOutputValue(context, "destFilePath", destFilePath);
		InputStream is = null;
		try {
			is = new FileInputStream(new File(destFilePath));
		} catch (FileNotFoundException e) {
			if (is != null) {
				try {
					is.close();
				} catch (Exception exx) {

				}
			}
			TranFailException ex = new TranFailException("PicCutOpStep001",
					"目标路径" + destFilePath + "不存在", e,
					new Object[] { destFilePath });
			throw ex;
		}
		setOutputValue(context, "fileCutStream", is);
		return 0;
	}

	private void abscut(String destImageFile, String srcImageFile, int x,
			int y, int destWidth, int destHeight) {
		try {
			Image img;
			ImageFilter cropFilter;
			// 读取源图像
			BufferedImage bi = ImageIO.read(new File(srcImageFile));
			int srcWidth = bi.getWidth(); // 源图宽度
			int srcHeight = bi.getHeight(); // 源图高度

			// add
			x = (x > 0) ? x : 0;
			y = (y > 0) ? y : 0;
			x = (x <= srcWidth) ? x : srcWidth;
			y = (y <= srcHeight) ? y : srcHeight;
			destWidth = (destWidth > 0) ? destWidth : 0;
			destHeight = (destHeight > 0) ? destHeight : 0;
			destWidth = ((destWidth + x) < srcWidth) ? destWidth
					: (srcWidth - x);
			destHeight = ((destHeight + y) < srcHeight) ? destHeight
					: (srcHeight - y);

			if (srcWidth >= destWidth && srcHeight >= destHeight) {
				Image image = bi.getScaledInstance(srcWidth, srcHeight,
						Image.SCALE_DEFAULT);
				// 改进的想法:是否可用多线程加快切割速度
				// 四个参数分别为图像起点坐标和宽高
				// 即: CropImageFilter(int x,int y,int width,int height)
				cropFilter = new CropImageFilter(x, y, destWidth, destHeight);
				img = Toolkit.getDefaultToolkit().createImage(
						new FilteredImageSource(image.getSource(), cropFilter));
				BufferedImage tag = new BufferedImage(destWidth, destHeight,
						BufferedImage.TYPE_INT_RGB);
				Graphics g = tag.getGraphics();
				g.drawImage(img, 0, 0, null); // 绘制缩小后的图
				g.dispose();
				// 输出为文件
				ImageIO.write(tag, "JPEG", new File(destImageFile));
			}
		} catch (Exception e) {

		}
	}

}
